类的实现
上一篇我们看完了HashMap的put方法,这篇我们继续看HashMpa中的其他方法。
get
获取HashMap中相应键的值
1 | public V get(Object key) { |
containsKey
是否包含指定键
1 | //直接调用getEntry方法,如果不返回空的话就存在 |
containsValue
是否包含指定值
1 | public boolean containsValue(Object value) { |
remove
移除指定key的映射
1 |
|
clear
清空hashMap的方法
1 | public void clear() { |
关于HashMap的改进
我们已经知道了HashMap内部是才用数组加链表的方式存储数据的,这种存储方式最好的情况就是数组的每个位置上都只有一个Entry,不形成链表,这样我们查找的效率为O(1),最糟糕的状况呢就是所有的元素都被分配到了一数组的某一个位置上,这样退化成为一个链表,时间复杂度为O(n),jdk8中为了改进这种情况,引入了红黑树的结构,当链表的长度超过8的时候,链表将转化为红黑树结构,以提高查找性能【这里就不做分析了】,这也是jdk8中最大的改进了。
与HashTable的对比
顺带着看了一下HashTable的源码,大致和HashMap相似,只不过主要操作方法加上了synchronized关键字,这也是我们熟悉的HashTable是同步的这个特性,但还是有一些不通,我们来看下:
不允许空值
HashTable中不允许null值,它并没有对null值做处理
1
2
3
4
5
6
7
8
9
10
11//当键为null的时候调用hashCode方法将抛出NullPointerException
private int hash(Object k) {
// hashSeed will be zero if alternative hashing is disabled.
return hashSeed ^ k.hashCode();
}
//value为空是直接抛出NullPointerException
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}初始容量和扩容方式
HashTable的初始容量是11,当扩容时,扩大到当前的2n+1
1 |
|
hash算法不一样
HashTable中的hash算法并没有HashMap那么复杂,只做了简单的按位异或操作,而计算数组索引则只用了取模操作
1
2
3
4
5
6private int hash(Object k) {
// hashSeed will be zero if alternative hashing is disabled.
return hashSeed ^ k.hashCode();
}
int index = (hash & 0x7FFFFFFF) % tab.length;HashTable是个过时的容器,这里就不大篇幅的展开了,如果需要使用同步的Map,请使用Collections.synchronizedMap(new HashMap(…))或者更高性能的ConcurrentHashMap
完!
**以上为个人理解,水平有限,难免出错,欢迎交流,共同进步**
—唉感觉进度好慢,但是也急不来的,加油!